use std::time::Duration;

use tokio::{io::{AsyncWriteExt, BufReader}, net::TcpStream, time::timeout};

use crate::error::AppErr;

use super::proto::{make_proto, read_proto};


pub struct Client {
    stream: BufReader<TcpStream>,
    cnt: u16,
}

impl Client {

    pub async fn connect(address: &str) -> Result<Self, AppErr> {
        let fut = TcpStream::connect(address);
        let stream = timeout(Duration::from_secs(3), fut).await
            .map_err(|_| AppErr::RobotNet("连接机械臂失败 连接超时了"))??
        ;
        Ok(Client { stream: BufReader::with_capacity(2048, stream), cnt: 0 })
    }

    pub async fn request(&mut self, cmd_id: u32, data: &str) -> Result<(), AppErr> {
        let cnt = self.cnt;
        self.cnt = self.cnt.wrapping_add(1);

        let body = make_proto(cnt, cmd_id, data);
        self.stream.write_all(body.as_bytes()).await?;
        let result = timeout(Duration::from_secs(3), read_proto(&mut self.stream)).await
            .map_err(|_| AppErr::RobotNet("机械臂读取数据超时"))??;

        let ret: Vec<&str> = result.split("III").collect();
        if ret.len() != 6 {
            return Err(AppErr::RobotService("机械臂返回数据错误"));
        }
        let ret_data = ret[4];
        if ret_data != "1" {
            return Err(AppErr::RobotService("机械臂执行失败"));
        }

        Ok(())
    }
}







